#define BLINKER_WIFI
//#define BLINKER_ESP_SMARTCONFIG 
#include <Blinker.h>
#include "ESP32_CAM_SERVER.h"
#include <HardwareSerial.h> 

HardwareSerial MySerial_stm32(1);  

char auth[] = "7a47c611c489"; // Blinker key
char ssid[] = "HUAWEI-ESLAB458"; // WiFi name
char pswd[] = "12345678"; // WiFi password

bool setup_camera = false;

// Define variables to store x, y, z values
int xValue = 0;
int yValue = 0;
int zValue = 0;

uint8_t Start_flag = 0;

uint8_t targetHeatingTime = 0;
uint8_t targetHeatingTemp = 0;
uint8_t targetUVingTime = 0;

uint8_t currentHeatingTime = 0;
uint8_t currentUVingTime = 0;

uint8_t changeHeatTimeParameterFlag = 0;
uint8_t changeHeatTempParameterFlag = 0;
uint8_t changeUVTimeParameterFlag   = 0;

uint8_t sendFlag = 0;

int16_t BlinkerTimeYear;
int8_t  BlinkerTimeMonth;
int8_t  BlinkerTimeMday;
int8_t  BlinkerTimeHour;
int8_t  BlinkerTimeMin;

uint32_t BlinkerTime;

#define Number_1 "num-1j2"
#define Number_2 "num-xit"
#define Number_3 "num-pwz"
#define Number_4 "num-rsk"

#define BUTTON_1 "btn-lvu"

#define Slider_1 "ran-wwb"
#define Slider_2 "ran-p5t"
#define Slider_3 "ran-uca"

#define FRAME_HEADER 0x7B  // 帧头 '{'
#define FRAME_TAIL   0x7D  // 帧尾 '}'
#define BUFFER_SIZE  24    // 数据包大小
#define SEND_SIZE 11    // 发送数据包大小改为11字节

// struct SensorData {
//     uint16_t temp;      // 环境温度
//     uint16_t humidity;  // 环境湿度
//     uint16_t voltage;   // 电压值
// };
struct SensorData {
    uint16_t Pitch;
    uint16_t Roll;
    uint16_t Yaw;
};

SensorData sensorData;
uint8_t dataBuffer[BUFFER_SIZE];
uint8_t bufferIndex = 0;

// 在全局变量区域添加发送数据缓冲区
uint8_t sendBuffer[SEND_SIZE];

BlinkerNumber Number1(Number_1);
BlinkerNumber Number2(Number_2);
BlinkerNumber Number3(Number_3);
BlinkerNumber Number4(Number_4);

BlinkerButton Button1(BUTTON_1);

BlinkerSlider Slider1(Slider_1); // Lifting servo position control slider
BlinkerSlider Slider2(Slider_2); // Tongs servo position control slider
BlinkerSlider Slider3(Slider_3); // Swing servo position control slider

void slider1_callback(int32_t value) // Lifting servo control
{
    xValue = value;
    targetHeatingTime = value;
    changeHeatTimeParameterFlag = 1;
    sendFlag = 1;
}

void slider2_callback(int32_t value) // Tongs servo control
{
    yValue = value;
    targetHeatingTemp = value;
    changeHeatTempParameterFlag = 1;
    sendFlag = 1;
}

void slider3_callback(int32_t value) // Swing servo control
{
    zValue = value;
    targetUVingTime = value;
    changeUVTimeParameterFlag = 1;
    sendFlag = 1;
}

void button1_callback(const String & state) // Grab object
{
    if (state == BLINKER_CMD_BUTTON_PRESSED) {
        Start_flag = !Start_flag;
    }
    sendFlag = 1;
}

void dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);
    Blinker.vibrate();
    BlinkerTime = millis();
    Blinker.print("millis", BlinkerTime);
}

uint8_t calculateChecksum(uint8_t *buffer, int length) {
    uint8_t checksum = 0;
    for(int i = 0; i < length; i++) {
        checksum ^= buffer[i];
    }
    return checksum;
}

bool parseDataPacket(uint8_t *buffer) {
    // 检查帧头和帧尾
    if(buffer[0] != FRAME_HEADER || buffer[23] != FRAME_TAIL) {
        return false;
    }

    // 验证校验和
    uint8_t receivedChecksum = buffer[22];
    if(calculateChecksum(buffer, 22) != receivedChecksum) {
        return false;
    }

    // 解析数据
    //sensorData.temp = (buffer[2] << 8) | buffer[3];
    //sensorData.humidity = (buffer[4] << 8) | buffer[5];
    //sensorData.voltage = (buffer[6] << 8) | buffer[7];
    //currentHeatingTime  = buffer[6];
    //currentUVingTime    = buffer[7];

    sensorData.Pitch = buffer[2];
    sensorData.Roll = buffer[3];
    sensorData.Yaw = buffer[4];


    return true;
}

void receiveSerialData() {
    while(MySerial_stm32.available() > 0) {
        uint8_t receivedByte = MySerial_stm32.read();

        // 如果是帧头或者已经开始接收数据
        if(receivedByte == FRAME_HEADER || bufferIndex > 0) {
            dataBuffer[bufferIndex++] = receivedByte;

            // 接收到完整数据包
            if(bufferIndex == BUFFER_SIZE) {
                if(parseDataPacket(dataBuffer)) {
                    // 数据解析成功，可以打印调试信息
                } else {
                    Serial.println("Data packet validation failed!");
                }
                bufferIndex = 0; // 重置缓冲区索引
            }
        }

        // 缓冲区溢出保护
        if(bufferIndex >= BUFFER_SIZE) {
            bufferIndex = 0;
        }
    }
}

// 修改发送函数
void sendDataToSTM32() {
    // 填充帧头
    sendBuffer[0] = FRAME_HEADER;
    
    sendBuffer[1] = Start_flag;
    sendBuffer[2] = targetHeatingTime;
    sendBuffer[3] = targetHeatingTemp;
    sendBuffer[4] = targetUVingTime;
    sendBuffer[5] = changeHeatTimeParameterFlag;
    sendBuffer[6] = changeHeatTempParameterFlag;
    sendBuffer[7] = changeUVTimeParameterFlag;
    sendBuffer[8] = BlinkerTimeMin;
    
    // 填充校验和
    sendBuffer[9] = calculateChecksum(sendBuffer, 9);
    
    // 填充帧尾
    sendBuffer[10] = FRAME_TAIL;
    
    // 通过串口发送数据
    MySerial_stm32.write(sendBuffer, SEND_SIZE);
}

void setup()
{
    Blinker.setTimezone(8.0);

    Serial.begin(115200);
    MySerial_stm32.begin(115200, SERIAL_8N1, 14, 15);     //IO14 --->RX_PIN
                                                          //IO15 --->TX_PIN
    BLINKER_DEBUG.stream(Serial);

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);

    Button1.attach(button1_callback);

    Slider1.attach(slider1_callback);
    Slider2.attach(slider2_callback);
    Slider3.attach(slider3_callback);
}

void loop()
{
    Blinker.run();
    
    BlinkerTimeYear   = Blinker.year();
    BlinkerTimeMonth  = Blinker.month();
    BlinkerTimeMday   = Blinker.mday();
    BlinkerTimeHour   = Blinker.hour();
    BlinkerTimeMin    = Blinker.minute();

   // if(sendFlag ==1)
    {
      sendDataToSTM32();
      sendFlag = 0;
      changeHeatTimeParameterFlag = 0;
      changeHeatTempParameterFlag = 0;
      changeUVTimeParameterFlag   = 0;
    }

    receiveSerialData();

    if (Blinker.connected() && !setup_camera) {
        setupCamera();
        setup_camera = true;
        Blinker.printObject("video", "{\"str\":\"mjpg\",\"url\":\"http:// "+ WiFi.localIP().toString() + "\"}");
    }

    if(Start_flag)
    {
      Button1.icon("icon_1");
      Button1.color("#FFFFFF");
      Button1.text("START");
      Button1.print();
    }
    else
    {
        Button1.icon("icon_1");
        Button1.color("#FFFFFF");
        Button1.text("STOP");
        Button1.print();
    }

    Number1.icon("icon_1");
    Number1.color("#FFFFFF");
    Number1.unit("Pitch");
    Number1.print(sensorData.Pitch);
    
    Number2.icon("icon_1");
    Number2.color("#FFFFFF");
    Number2.unit("Roll");
    Number2.print(sensorData.Roll);
    
    Number3.icon("icon_1");
    Number3.color("#FFFFFF");
    Number3.unit("Yaw");
    Number3.print(sensorData.Yaw);
    
    Number4.icon("icon_1");
    Number4.color("#FFFFFF");
    Number4.unit("Number");
    Number4.print(currentUVingTime);
}
